package com.smashcrush.client.gwt.client.editor;

import java.util.Map;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.widgetideas.client.GlassPanel;
import com.smashcrush.client.gwt.SecurityContext;
import com.smashcrush.client.gwt.manager.ScriptsManager;
import com.smashcrush.client.gwt.service.TestingServiceAsync;
import com.smashcrush.client.gwt.util.WidgetUtil;
import com.smashcrush.model.BrowserType;
import com.smashcrush.model.Script;
import com.smashcrush.model.ScriptExecutionStatus;
import com.smashcrush.model.ScriptResults;
import com.smashcrush.model.ScriptSourceType;

public class ScriptEditor extends Composite {

	Script script;

	ScriptEditorGeneralTab generalTab;

	ScriptEditorParametersTab parametersTab;

	ScriptEditorSourceTab sourceTab;

	ScriptProgress progress;

	public ScriptEditor() {
		this(new Script());
	}

	public ScriptEditor(Script script) {
		this.script = script;

		Grid grid = new Grid(2, 1);
		grid.setSize("100%", "100%");

		generalTab = new ScriptEditorGeneralTab();
		parametersTab = new ScriptEditorParametersTab();
		sourceTab = new ScriptEditorSourceTab();

		TabPanel tabPanel = new TabPanel();
		grid.setWidget(0, 0, tabPanel);
		tabPanel.setSize("100%", "100%");
		tabPanel.add(generalTab, "General");
		tabPanel.add(parametersTab, "Parameters");
		tabPanel.add(sourceTab, "Source");

		tabPanel.selectTab(0);

		grid.setWidget(0, 0, tabPanel);

		HorizontalPanel horiz = new HorizontalPanel();
		grid.setWidget(1, 0, horiz);

		Button save = new Button("Save", new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				save();
			}
		});
		horiz.add(save);

		Button runButton = new Button("Run", new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				run();
			}
		});
		horiz.add(runButton);

		if (script.getId() != null) {
			load();
		}

		initWidget(grid);
	}

	public ScriptEditorGeneralTab getGeneralTab() {
		return generalTab;
	}

	public ScriptEditorParametersTab getParametersTab() {
		return parametersTab;
	}

	public ScriptEditorSourceTab getEditorTab() {
		return sourceTab;
	}

	private void load() {
		generalTab.getNameTextBox().setText(script.getName());
		generalTab.getDescriptionTextArea().setText(script.getDescription());
		WidgetUtil.setListBoxValue(generalTab.getScriptSourceType(), script
				.getScriptSourceType().toString());
		WidgetUtil.setListBoxValue(generalTab.getBrowserType(), script
				.getBrowserType().toString());
		sourceTab.getTextArea().setText(script.getSource());
	}

	public void run() {
		final GlassPanel glassPanel = new GlassPanel(false);
		RootPanel.get().add(glassPanel, 0, 0);

		progress = new ScriptProgress();
		progress.setModal(true);
		progress.center();

		progress.setOnCloseCommand(new Command() {

			@Override
			public void execute() {
				glassPanel.removeFromParent();
			}
		});

		progress.show();

		/*
		 * OrderedCallbackManager manager = new OrderedCallbackManager() {
		 * 
		 * String sessionId = null;
		 * 
		 * String token = SecurityContext.get().getToken();
		 * 
		 * @Override public void onResponse() {
		 * 
		 * if (getException() != null) {
		 * progress.setError(getException().getMessage()); return; }
		 * 
		 * System.out.println("response: " + getResult()); if (getLastKey() ==
		 * null) { progress.setText("Opening Session...");
		 * progress.setProgress(25);
		 * BrowserServiceAsync.RPC.get().openSession(token, BrowserType.FireFox,
		 * "google.com", generateCallback("openSession")); } else if
		 * (getLastKey().equals("openSession")) {
		 * progress.setText("Executing Script..."); progress.setProgress(50);
		 * sessionId = (String) getResult(); ExecuteScriptParameters parameters
		 * = new ExecuteScriptParameters();
		 * parameters.setScript(sourceTab.getTextArea().getText());
		 * BrowserServiceAsync.RPC.get().executeScript(token, sessionId,
		 * parameters, generateCallback("executeScript")); } else if
		 * (getLastKey().equals("executeScript")) { Map<String, String>
		 * returnMap = (Map) getResult(); progress.setResults(returnMap);
		 * progress.setText("Closing Session..."); progress.setProgress(100);
		 * BrowserServiceAsync.RPC.get().closeSession(token, sessionId,
		 * generateCallback("closeSession")); }
		 * 
		 * }
		 * 
		 * };
		 */

		// manager.run();

		System.out.println("sending..." + sourceTab.getTextArea().getText());

		Script script = new Script();
		script.setSource(sourceTab.getTextArea().getText());

		String browserTypeStr = WidgetUtil.getListBoxValue(generalTab
				.getBrowserType());
		BrowserType browserType = BrowserType.valueOf(browserTypeStr);
		script.setBrowserType(browserType);

		TestingServiceAsync.RPC.get().pushScript(
				SecurityContext.get().getToken(), script,
				new AsyncCallback<Void>() {

					@Override
					public void onSuccess(Void result) {
						// progress.setResults(result);
						progress.setText("Closing Session...");
						poll();
					}

					@Override
					public void onFailure(Throwable caught) {
						progress.setError(caught.getMessage());
					}
				});
	}

	private void poll() {
		TestingServiceAsync.RPC.get().pollResults(
				SecurityContext.get().getToken(),
				new AsyncCallback<ScriptResults>() {

					@Override
					public void onSuccess(ScriptResults results) {
						progress.setResults(results);
						if (!results.getPollResultsStatus().equals(
								ScriptExecutionStatus.Done)) {

							poll();
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						caught.printStackTrace();
						Window.alert(caught.getMessage());
					}
				});
	}

	private void save() {

		// Assign Values
		script.setName(generalTab.getNameTextBox().getValue());
		script.setDescription(generalTab.getDescriptionTextArea().getValue());
		script.setSource(sourceTab.getTextArea().getValue());

		String sourceTypeStr = generalTab.getScriptSourceType().getValue(
				generalTab.getScriptSourceType().getSelectedIndex());
		ScriptSourceType sourceType = ScriptSourceType.valueOf(sourceTypeStr);
		script.setScriptSourceType(sourceType);

		Map<String, String> errors = script.validate();

		if (!errors.isEmpty()) {
			Window.alert(errors.values().iterator().next());
		} else {
			ScriptsManager.get().saveScript(script);
		}
	}
}
